import type { App, ObjectDirective, DirectiveBinding } from 'vue';

/**
 * 鼠标进入背景色（渐进色）
 * */
// 指令配置类型（支持自定义进入渐变）
interface HoverGradientOptions {
  enterGradient?: string; // 鼠标进入时的渐变背景
  duration?: number; // 过渡动画时长（秒）
}

// 默认配置（使用指定渐变）
const DEFAULT_OPTIONS: HoverGradientOptions = {
  enterGradient: 'linear-gradient(90deg, #F78647 0%, #E1603D 100%)',
  duration: 0.5,
};

// 注入全局过渡样式
const injectGlobalStyles = () => {
  if (document.getElementById('v-hover-gradient-styles')) return;

  const style = document.createElement('style');
  style.id = 'v-hover-gradient-styles';
  style.textContent = `
    .v-hover-gradient {
      transition: background 0.5s ease !important;
    }
  `;
  document.head.appendChild(style);
};

// 指令逻辑
const directive: ObjectDirective<HTMLElement, HoverGradientOptions> = {
  // 绑定阶段注入样式
  // @ts-ignore
  bind(el: HTMLElement) {
    injectGlobalStyles();
  },

  // 元素挂载时
  mounted(el: HTMLElement, binding: DirectiveBinding<HoverGradientOptions>) {
    const options = { ...DEFAULT_OPTIONS, ...binding.value };

    // 关键：获取元素原始背景（支持渐变、纯色、透明）
    const getOriginalBackground = () => {
      // 1. 优先获取内联样式（元素上直接设置的 background/background-image）
      if (el.style.background) return el.style.background;
      if (el.style.backgroundImage) return el.style.backgroundImage;

      // 2. 获取计算样式（CSS类中定义的背景）
      const computedBg = getComputedStyle(el).background;
      return computedBg || '';
    };

    // 存储原始背景（用于鼠标离开时恢复）
    const originalBackground = getOriginalBackground();
    // 添加基础类名（应用过渡动画）
    el.classList.add('v-hover-gradient');
    // 设置过渡时长
    if (options.duration) {
      el.style.transitionDuration = `${options.duration}s`;
    }

    // 鼠标进入：应用渐变背景
    const handleMouseEnter = () => {
      // 对于渐变背景，需设置 background-image 或 background
      el.style.background = options.enterGradient!;
    };

    // 鼠标离开：恢复原始背景
    const handleMouseLeave = () => {
      // 恢复原始背景（可能是渐变、纯色或透明）
      el.style.background = originalBackground;
    };

    // 绑定事件
    el.addEventListener('mouseenter', handleMouseEnter);
    el.addEventListener('mouseleave', handleMouseLeave);

    // 存储数据供后续使用
    (el as any).vHoverGradientData = {
      originalBackground,
      handlers: { handleMouseEnter, handleMouseLeave },
    };
  },

  // 指令参数更新时
  updated(el: HTMLElement, binding: DirectiveBinding<HoverGradientOptions>) {
    if (!binding.value) return;

    const data = (el as any).vHoverGradientData;
    if (!data) return;

    // 移除旧事件
    el.removeEventListener('mouseenter', data.handlers.handleMouseEnter);
    el.removeEventListener('mouseleave', data.handlers.handleMouseLeave);

    // 更新配置
    const options = { ...DEFAULT_OPTIONS, ...binding.value };
    if (options.duration) {
      el.style.transitionDuration = `${options.duration}s`;
    }

    // 新事件处理
    const newEnterHandler = () => {
      el.style.background = options.enterGradient!;
    };
    const newLeaveHandler = () => {
      el.style.background = data.originalBackground;
    };

    el.addEventListener('mouseenter', newEnterHandler);
    el.addEventListener('mouseleave', newLeaveHandler);
    data.handlers = { handleMouseEnter: newEnterHandler, handleMouseLeave: newLeaveHandler };
  },

  // 元素卸载时清理
  unmounted(el: HTMLElement) {
    const data = (el as any).vHoverGradientData;
    if (data) {
      el.removeEventListener('mouseenter', data.handlers.handleMouseEnter);
      el.removeEventListener('mouseleave', data.handlers.handleMouseLeave);
      el.classList.remove('v-hover-gradient');
      // 恢复原始背景，避免残留
      el.style.background = data.originalBackground;
      delete (el as any).vHoverGradientData;
    }
  },
};

// 全局注册指令
export const setupHoverGradientDirective = (app: App) => {
  app.directive('hover-gradient', directive);
};

export default directive;
